package org.example;

import org.example.autowiredbean.AutoBeanService;
import org.example.configbean.DemoConfig;
import org.example.constuctorbean.ConsBuildService;
import org.example.factorybean.TestBeanFactory;
import org.example.importbean.ImportBean;
import org.example.importbean.ImportConfig;
import org.example.resourcebean.TestResourceService;
import org.example.xmlbean.XmlContextService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.annotation.Resource;

@SpringBootApplication

public class SpringBeanApplication implements CommandLineRunner {

  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

  AnnotationConfigApplicationContext annoContext = new AnnotationConfigApplicationContext(ImportConfig.class);

  @Autowired
  private AutoBeanService autoBeanService;

  @Resource(name = "ServiceA")
  private TestResourceService testServiceA;

  @Resource(name = "ServiceB")
  private TestResourceService testServiceB;

  @Resource(name = "testConfig")
  private DemoConfig.Demo demo;

  public static void main(String[] args) {
    SpringApplication.run(SpringBeanApplication.class, args);
  }

  @Override
  public void run(String... args) {

    // 写代码实现 Spring Bean的装配，方式越多越好（XML、Annotation 都可以）【简单】
    // - 在XML中进行显式配置:
    // 1. 上下文获取XML配置bean  //  name – the name of the bean to retrieve  实际上是按名取
    System.out.println("1.context.getBean");
    XmlContextService xmlContextService = (XmlContextService)context.getBean("xmlContextService");
    xmlContextService.printName();

    // 2.XML 设值注入 （id，name）
    System.out.println("2.property setter");
    xmlContextService.printNameByPropertySetter();
    // 3 构造器
    System.out.println("3.Constructor");
    ConsBuildService consBuildService = (ConsBuildService)context.getBean("consBuildService");
    consBuildService.printName();
    // 4.工厂方法
    System.out.println("4.Factory");
    TestBeanFactory testBeanFactory = (TestBeanFactory)context.getBean("testBeanFactory");
    testBeanFactory.createBean().printName();

    //  - 在java中进行显示配置（通过注解）:
    // 5.@Autowired 按ID注入
    //   - 隐式的bean发现机制和自动装配。 @Bean,@Component +@Autowired  不单独写了
    System.out.println("5.@Autowired");
    autoBeanService.printName();
    // 6.按Name注入
    System.out.println("6.@Resource   name");
    testServiceA.printMyName();
    testServiceB.printMyName();

    // 7.基于Java配置类的装配:
    System.out.println("7.基于Java配置类的装配:");
    System.out.println(demo.getName());

    // 8.@Import引入
    System.out.println("8.@Import引入:");
    ImportBean importBean = annoContext.getBean(ImportBean.class);
    importBean.printMyName();

  }

}
